package com.dianning.service.imp;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import org.apache.commons.logging.*;

import com.dianning.bean.AdSpace;
import com.dianning.bean.Area;
import com.dianning.bean.Channel;
import com.dianning.bean.ChannelContact;
import com.dianning.bean.Info;
import com.dianning.bean.InfoExpand;
import com.dianning.bean.Reserve;
import com.dianning.bean.TradingArea;
import com.dianning.bean.UserInfo;
import com.dianning.bean.Visitor;
import com.dianning.comm.Constant;
import com.dianning.comm.OrderObj;
import com.dianning.dao.AdAdsDAO;
import com.dianning.dao.AdSpaceDAO;
import com.dianning.dao.AreaDAO;
import com.dianning.dao.ChannelContactDAO;
import com.dianning.dao.ChannelDAO;
import com.dianning.dao.CompanyDAO;
import com.dianning.dao.InfoDAO;
import com.dianning.dao.InfoExpandDAO;
import com.dianning.dao.ProfileDAO;
import com.dianning.dao.ReserveDAO;
import com.dianning.dao.TradingAreaDAO;
import com.dianning.dao.UserDetailDAO;
import com.dianning.dao.UserInfoDAO;
import com.dianning.dao.VisitorDAO;
import com.dianning.exception.DianningException;
import com.dianning.fio.InfoPicUploadFile;
import com.dianning.service.AdService;
import com.dianning.service.Cache;
import com.dianning.service.InfoService;
import com.dianning.service.VisitorService;
import com.dianning.service.web.PageList;
import com.dianning.service.web.Pages;

public class InfoServiceImp implements InfoService {

	private static final Log logger = LogFactory.getLog(InfoServiceImp.class);

	private InfoDAO infoDAO;
	private InfoExpandDAO infoExpandDAO;
	private AreaDAO areaDAO;
	private TradingAreaDAO tradingAreaDAO;
	private ChannelContactDAO channelContactDAO;
	private ChannelDAO channelDAO;
	private UserInfoDAO userInfoDAO;
	private UserDetailDAO userDetailDAO;
	private CompanyDAO companyDAO;
	private ProfileDAO profileDAO;
	private InfoPicUploadFile infoPicUploadFile;
	private ReserveDAO reserveDAO;
	private Cache infoListCache;
	private Cache infoChannelCache;
	private Cache areaCache;
	
	public InfoDAO getInfoDAO() {
		return infoDAO;
	}

	public void setInfoDAO(InfoDAO infoDAO) {
		this.infoDAO = infoDAO;
	}

	public InfoExpandDAO getInfoExpandDAO() {
		return infoExpandDAO;
	}

	public void setInfoExpandDAO(InfoExpandDAO infoExpandDAO) {
		this.infoExpandDAO = infoExpandDAO;
	}
	
	public AreaDAO getAreaDAO() {
		return areaDAO;
	}

	public void setAreaDAO(AreaDAO areaDAO) {
		this.areaDAO = areaDAO;
	}

	public TradingAreaDAO getTradingAreaDAO() {
		return tradingAreaDAO;
	}

	public void setTradingAreaDAO(TradingAreaDAO tradingAreaDAO) {
		this.tradingAreaDAO = tradingAreaDAO;
	}
	
	public ChannelContactDAO getChannelContactDAO() {
		return channelContactDAO;
	}

	public void setChannelContactDAO(ChannelContactDAO channelContactDAO) {
		this.channelContactDAO = channelContactDAO;
	}

	public ChannelDAO getChannelDAO() {
		return channelDAO;
	}

	public void setChannelDAO(ChannelDAO channelDAO) {
		this.channelDAO = channelDAO;
	}

	public UserInfoDAO getUserInfoDAO() {
		return userInfoDAO;
	}

	public void setUserInfoDAO(UserInfoDAO userInfoDAO) {
		this.userInfoDAO = userInfoDAO;
	}
	
	public UserDetailDAO getUserDetailDAO() {
		return userDetailDAO;
	}

	public void setUserDetailDAO(UserDetailDAO userDetailDAO) {
		this.userDetailDAO = userDetailDAO;
	}

	public CompanyDAO getCompanyDAO() {
		return companyDAO;
	}

	public void setCompanyDAO(CompanyDAO companyDAO) {
		this.companyDAO = companyDAO;
	}

	public ProfileDAO getProfileDAO() {
		return profileDAO;
	}

	public void setProfileDAO(ProfileDAO profileDAO) {
		this.profileDAO = profileDAO;
	}

	public InfoPicUploadFile getInfoPicUploadFile() {
		return infoPicUploadFile;
	}

	public void setInfoPicUploadFile(InfoPicUploadFile infoPicUploadFile) {
		this.infoPicUploadFile = infoPicUploadFile;
	}
	
	public ReserveDAO getReserveDAO() {
		return reserveDAO;
	}

	public void setReserveDAO(ReserveDAO reserveDAO) {
		this.reserveDAO = reserveDAO;
	}

	public Cache getInfoListCache() {
		return infoListCache;
	}

	public void setInfoListCache(Cache infoListCache) {
		this.infoListCache = infoListCache;
	}
	
	public Cache getInfoChannelCache() {
		return infoChannelCache;
	}

	public void setInfoChannelCache(Cache infoChannelCache) {
		this.infoChannelCache = infoChannelCache;
	}

	public Cache getAreaCache() {
		return areaCache;
	}

	public void setAreaCache(Cache areaCache) {
		this.areaCache = areaCache;
	}

	/**
	 * 保存信息
	 * @param info
	 * @param infoexpands
	 * @return Info
	 */
	public Info saveInfo(Info info,List infoExpands){
		info = this.getInfoDAO().saveInfo(info);
		if(infoExpands!=null && !infoExpands.isEmpty()){
			for(int i=0;i<infoExpands.size();i++){
				InfoExpand infoex = (InfoExpand) infoExpands.get(i);
				infoex.setInfoId(info.getId());
				this.getInfoExpandDAO().saveInfoExpand(infoex);
			}
		}
		if(info.getPhoto()!=null && !info.getPhoto().isEmpty()){
			String picpath = (String) info.getPhoto().get(0);
			this.getInfoPicUploadFile().saveAvatar(picpath, info.getId());
		}
		//添加用户信用值
		UserInfo ui = this.getUserInfoDAO().findUserInfoById(info.getUid());
		ui.setCredit(ui.getCredit() + Constant.INFO_CREDIT_NUMBER);
		this.getUserInfoDAO().updateUserInfo(ui);
		return info;
	}
	
	public Info updateInfo(Info info,List infoExpands){
		info = this.getInfoDAO().updateInfo(info);
		if(infoExpands!=null && !infoExpands.isEmpty()){
			for(int i=0;i<infoExpands.size();i++){
				InfoExpand infoex = (InfoExpand) infoExpands.get(i);
				this.getInfoExpandDAO().updateInfoExpand(infoex);
			}
		}
		if(info.getPhoto()!=null && !info.getPhoto().isEmpty()){
			String picpath = (String) info.getPhoto().get(0);
			this.getInfoPicUploadFile().saveAvatar(picpath, info.getId());
		}
		if(Constant.USE_CACHE){
			this.getInfoListCache().remove("[infoExpands]["+info.getId()+"]");
		}
		return info;
	}
	/**
	 * 根据主键获取Info对象
	 * 
	 * @param id
	 * 			long
	 * @return Info
	 * 			Info对象
	 */
	public Info findInfoById(long id){

		Info info = this.getInfoDAO().findInfoById(id);
		

		//地区
		if(info.getAreaId() == 0){
			Area area = new Area();
			area.setId(0);
			area.setAreaname(Constant.AREA_NAME);
			info.setArea(area);
		}else{
			if(Constant.USE_CACHE){
				Area area = (Area)this.getAreaCache().get("[area]["+info.getAreaId()+"]");
				if(area == null){
					area = this.getAreaDAO().findAreaById(info.getAreaId());
					this.getAreaCache().add("[area]["+info.getAreaId()+"]",area);
				}
				info.setArea(area);
			}else{
				info.setArea(this.getAreaDAO().findAreaById(info.getAreaId()));
			}
		}
		//商圈
		if(info.getTradingareaId() == 0){
			TradingArea tradingArea = new TradingArea();
			tradingArea.setAreaId(0);
			tradingArea.setId(0);
			tradingArea.setTradingname("");
			info.setTradingArea(tradingArea);
		}else{
			if(Constant.USE_CACHE){
				TradingArea tradingArea = (TradingArea) this.getAreaCache().get("[tradingArea]["+info.getTradingareaId()+"]");
				if(tradingArea == null){
					tradingArea = this.getTradingAreaDAO().findTradingAreaById(info.getTradingareaId());
					this.getAreaCache().add("[tradingArea]["+info.getTradingareaId()+"]",tradingArea);
				}
				info.setTradingArea(tradingArea);
			}else{
				info.setTradingArea(this.getTradingAreaDAO().findTradingAreaById(info.getTradingareaId()));
			}
		}
		//频道
		if(Constant.USE_CACHE){
			ChannelContact scc = (ChannelContact) this.getInfoChannelCache().get("[channelContact]["+info.getCcid()+"]");
			if(scc == null){
				scc = this.getChannelContactDAO().findChannelContactById(info.getCcid());
				this.getInfoChannelCache().add("[channelContact]["+info.getCcid()+"]",scc);
			}
			Channel smallChannel = (Channel) this.getInfoChannelCache().get("[channel]["+scc.getChannelId()+"]");
			if(smallChannel == null){
				smallChannel = this.getChannelDAO().findChannelById(scc.getChannelId());
				this.getInfoChannelCache().add("[channel]["+scc.getChannelId()+"]",smallChannel);
			}
			ChannelContact bcc = (ChannelContact) this.getInfoChannelCache().get("[channelContact]["+scc.getParentId()+"]");
			if(bcc == null){
				bcc = this.getChannelContactDAO().findChannelContactById(scc.getParentId());
				this.getInfoChannelCache().add("[channelContact]["+scc.getParentId()+"]",bcc);
			}
			Channel bigChannel = (Channel) this.getInfoChannelCache().get("[channel]["+bcc.getChannelId()+"]");
			if(bigChannel == null){
				bigChannel = this.getChannelDAO().findChannelById(bcc.getChannelId());
				this.getInfoChannelCache().add("[channel]["+bcc.getChannelId()+"]",bigChannel);
			}
			info.setSmallChannel(smallChannel);
			info.setChannel(bigChannel);
		}else{
    		ChannelContact scc = this.getChannelContactDAO().findChannelContactById(info.getCcid());
    		info.setSmallChannel(this.getChannelDAO().findChannelById(scc.getChannelId()));
    		ChannelContact bcc = this.getChannelContactDAO().findChannelContactById(scc.getParentId());
    		info.setChannel(this.getChannelDAO().findChannelById(bcc.getChannelId()));
		}
		//扩展信息
		if(Constant.USE_CACHE){
			List infoExpands =(List) this.getInfoListCache().get("[infoExpands]["+info.getId()+"]");
			if(infoExpands==null){
				infoExpands=this.getInfoExpandDAO().findInfoExpandsByInfoId(info.getId());
				this.getInfoListCache().add("[infoExpands]["+info.getId()+"]",infoExpands);
			}
			info.setInfoExpands(infoExpands);
		}else{
			info.setInfoExpands(this.getInfoExpandDAO().findInfoExpandsByInfoId(info.getId()));
		}
		
		//用户信息
		info.setUserInfo(this.getUserInfoDAO().findUserInfoById(info.getUid()));
		info.setUserDetail(this.getUserDetailDAO().findUserDetailByUid(info.getUid()));
		//profile信息
		info.setProfile(this.getProfileDAO().findProfileByUid(info.getUid()));
		//公司
		info.setCompany(this.getCompanyDAO().findCompanyByUid(info.getUid()));
		
		return info;
	}
	
	/**
	 * 根据InfoID,Keyword获取InfoExpand对象
	 * @param infoId
	 * @param keyword
	 * @return InfoExpand
	 * 			InfoExpand对象
	 */
	public InfoExpand findInfoExpandByInfoIdKeyword(long infoId,String keyword){
		return this.getInfoExpandDAO().findInfoExpandByInfoIdKeyword(infoId, keyword);
	}
	
	/**
	 * 更新置顶信息
	 */
	public void updateCityTopInfo(){
		this.getInfoDAO().updateCityTopInfo();
	}
	public void updateAreaTopInfo(){
		this.getInfoDAO().updateAreaTopInfo();
	}
	public void updateCommendInfo(){
		this.getInfoDAO().updateCommendInfo();
	}
	public void updateTopReserves(){
		List reserves = this.getReserveDAO().findTopReserves();
		if(reserves != null){
			for(int i=0;i<reserves.size();i++){
				Reserve r = (Reserve) reserves.get(i);
				Info rInfo = this.getInfoDAO().findInfoById(r.getInfoId());
				if(r.getType().equalsIgnoreCase("city_top")){
					rInfo.setIsCityTop(1);
					rInfo.setCityTopTime(r.getEndTime());
				}
				if(r.getType().equalsIgnoreCase("area_top")){
					rInfo.setIsAreaTop(1);
					rInfo.setAreaTopTime(r.getEndTime());
				}
				if(r.getType().equalsIgnoreCase("refresh")){
					rInfo.setUpTime(new Date());
				}
				this.getInfoDAO().updateInfo(rInfo);
				//r.setStatus(0);
				//this.getReserveDAO().updateReserve(r);
				this.getReserveDAO().removeReserve(r);
			}
		}
	}

	/**
	 * 获取Info对象列表
	 * 
	 * @param uid
	 * @param cid
	 * @param ccid
	 * @param areaId
	 * @param tradingareaId
	 * @param title
	 * @param validated
	 * @param status
	 * @param oo
	 * @param pages
	 * @return PageList
	 */
	public PageList findInfos(long uid,long cid,long ccid,long areaId,long tradingareaId,int isbiz,int validated,int status,int isprofile,String title,List wherein,OrderObj[] oo, Pages pages){
		/*
		List infoIds = null;
		if(wherein!=null && !wherein.isEmpty()){
			for(int i=0;i<wherein.size();i++){
				String where = (String) wherein.get(i);
				if(i == 0){
					infoIds = this.getInfoExpandDAO().findInfoExpandInfoIds(where, null);
				}else{
					if(infoIds != null && !infoIds.isEmpty()){
						infoIds = this.getInfoExpandDAO().findInfoExpandInfoIds(where, infoIds);
					}
				}
			}
		}
		if((wherein!=null && !wherein.isEmpty())&&(infoIds==null || infoIds.isEmpty())){
			PageList pl = new PageList();
			pages.setTotalNum(0);
			pages.executeCount();
			pl.setObjectList(null);
			pl.setPages(pages);
        	return pl;
		}
		
		//处理置顶信息
		this.getInfoDAO().updateCityTopInfo();
		this.getInfoDAO().updateAreaTopInfo();
		this.getInfoDAO().updateCommendInfo();
		List reserves = this.getReserveDAO().findTopReserves();
		if(reserves != null){
			for(int i=0;i<reserves.size();i++){
				Reserve r = (Reserve) reserves.get(i);
				Info rInfo = this.getInfoDAO().findInfoById(r.getInfoId());
				if(r.getType().equalsIgnoreCase("city_top")){
					rInfo.setIsCityTop(1);
					rInfo.setCityTopTime(r.getEndTime());
				}
				if(r.getType().equalsIgnoreCase("area_top")){
					rInfo.setIsAreaTop(1);
					rInfo.setAreaTopTime(r.getEndTime());
				}
				if(r.getType().equalsIgnoreCase("refresh")){
					rInfo.setUpTime(new Date());
				}
				this.getInfoDAO().updateInfo(rInfo);
				r.setStatus(0);
				this.getReserveDAO().updateReserve(r);
			}
		}
		*/
		PageList pl = new PageList();
        if (pages.getTotalNum() == -1) {
            pages.setTotalNum(this.getInfoDAO().getInfoNum(uid, cid, ccid, areaId, tradingareaId,isbiz, validated, status,isprofile, title,wherein));
        }
        pages.executeCount();
        if(pages.getTotalNum() == 0){
        	pl.setObjectList(null);
        	pl.setPages(pages);
        	return pl;
        }
        List l = this.getInfoDAO().findInfos(uid, cid, ccid, areaId, tradingareaId, isbiz, validated, status, isprofile, title,wherein, oo,pages.getSpage(), pages.getPerPageNum());
        for(int i=0;i<l.size();i++){
        	Info info = (Info) l.get(i);
        	if(info.getAreaId() == 0){
    			Area area = new Area();
    			area.setId(0);
    			area.setAreaname(Constant.AREA_NAME);
    			info.setArea(area);
    		}else{
    			if(Constant.USE_CACHE){
    				Area area = (Area)this.getAreaCache().get("[area]["+info.getAreaId()+"]");
    				if(area == null){
    					area = this.getAreaDAO().findAreaById(info.getAreaId());
    					this.getAreaCache().add("[area]["+info.getAreaId()+"]",area);
    				}
    				info.setArea(area);
    			}else{
    				info.setArea(this.getAreaDAO().findAreaById(info.getAreaId()));
    			}
    		}
    		//商圈
    		if(info.getTradingareaId() == 0){
    			TradingArea tradingArea = new TradingArea();
    			tradingArea.setAreaId(0);
    			tradingArea.setId(0);
    			tradingArea.setTradingname("");
    			info.setTradingArea(tradingArea);
    		}else{
    			if(Constant.USE_CACHE){
    				TradingArea tradingArea = (TradingArea) this.getAreaCache().get("[tradingArea]["+info.getTradingareaId()+"]");
    				if(tradingArea == null){
    					tradingArea = this.getTradingAreaDAO().findTradingAreaById(info.getTradingareaId());
    					this.getAreaCache().add("[tradingArea]["+info.getTradingareaId()+"]",tradingArea);
    				}
    				info.setTradingArea(tradingArea);
    			}else{
    				info.setTradingArea(this.getTradingAreaDAO().findTradingAreaById(info.getTradingareaId()));
    			}
    		}
    		//频道
    		if(Constant.USE_CACHE){
    			ChannelContact scc = (ChannelContact) this.getInfoChannelCache().get("[channelContact]["+info.getCcid()+"]");
    			if(scc == null){
    				scc = this.getChannelContactDAO().findChannelContactById(info.getCcid());
    				this.getInfoChannelCache().add("[channelContact]["+info.getCcid()+"]",scc);
    			}
    			Channel smallChannel = (Channel) this.getInfoChannelCache().get("[channel]["+scc.getChannelId()+"]");
    			if(smallChannel == null){
    				smallChannel = this.getChannelDAO().findChannelById(scc.getChannelId());
    				this.getInfoChannelCache().add("[channel]["+scc.getChannelId()+"]",smallChannel);
    			}
    			ChannelContact bcc = (ChannelContact) this.getInfoChannelCache().get("[channelContact]["+scc.getParentId()+"]");
    			if(bcc == null){
    				bcc = this.getChannelContactDAO().findChannelContactById(scc.getParentId());
    				this.getInfoChannelCache().add("[channelContact]["+scc.getParentId()+"]",bcc);
    			}
    			Channel bigChannel = (Channel) this.getInfoChannelCache().get("[channel]["+bcc.getChannelId()+"]");
    			if(bigChannel == null){
    				bigChannel = this.getChannelDAO().findChannelById(bcc.getChannelId());
    				this.getInfoChannelCache().add("[channel]["+bcc.getChannelId()+"]",bigChannel);
    			}
    			info.setSmallChannel(smallChannel);
    			info.setChannel(bigChannel);
    		}else{
	    		ChannelContact scc = this.getChannelContactDAO().findChannelContactById(info.getCcid());
	    		info.setSmallChannel(this.getChannelDAO().findChannelById(scc.getChannelId()));
	    		ChannelContact bcc = this.getChannelContactDAO().findChannelContactById(scc.getParentId());
	    		info.setChannel(this.getChannelDAO().findChannelById(bcc.getChannelId()));
    		}
    		//扩展信息
    		if(Constant.USE_CACHE){
    			List infoExpands =(List) this.getInfoListCache().get("[infoExpands]["+info.getId()+"]");
    			if(infoExpands==null){
    				infoExpands=this.getInfoExpandDAO().findInfoExpandsByInfoId(info.getId());
    				this.getInfoListCache().add("[infoExpands]["+info.getId()+"]",infoExpands);
    			}
    			info.setInfoExpands(infoExpands);
    		}else{
    			info.setInfoExpands(this.getInfoExpandDAO().findInfoExpandsByInfoId(info.getId()));
    		}
    		//profile信息
    		info.setProfile(this.getProfileDAO().findProfileByUid(info.getUid()));
        }
        pl.setObjectList(l);
        pl.setPages(pages);
        return pl;
	}

	/**
	 * 获取Info对象列表
	 * 
	 * @param id
	 * @param ccid
	 * @param validated
	 * @param status
	 * @param orderby
	 * @param ascOrDesc
	 * @param firstResult
	 * @param maxResults
	 * @return List
	 */
	public List findInfos(long id,long uid,long ccid,int validated,int status,int isprofile,String orderby, int ascOrDesc, int firstResult, int maxResults){
		List l = this.getInfoDAO().findInfos(id, uid, ccid, validated, status, isprofile, orderby, ascOrDesc, firstResult, maxResults);
		if(l == null || l.isEmpty()){
			return null;
		}else{
			for(int i=0;i<l.size();i++){
				Info info = (Info) l.get(i);
				//频道
	    		if(Constant.USE_CACHE){
	    			ChannelContact scc = (ChannelContact) this.getInfoChannelCache().get("[channelContact]["+info.getCcid()+"]");
	    			if(scc == null){
	    				scc = this.getChannelContactDAO().findChannelContactById(info.getCcid());
	    				this.getInfoChannelCache().add("[channelContact]["+info.getCcid()+"]",scc);
	    			}
	    			Channel smallChannel = (Channel) this.getInfoChannelCache().get("[channel]["+scc.getChannelId()+"]");
	    			if(smallChannel == null){
	    				smallChannel = this.getChannelDAO().findChannelById(scc.getChannelId());
	    				this.getInfoChannelCache().add("[channel]["+scc.getChannelId()+"]",smallChannel);
	    			}
	    			ChannelContact bcc = (ChannelContact) this.getInfoChannelCache().get("[channelContact]["+scc.getParentId()+"]");
	    			if(bcc == null){
	    				bcc = this.getChannelContactDAO().findChannelContactById(scc.getParentId());
	    				this.getInfoChannelCache().add("[channelContact]["+scc.getParentId()+"]",bcc);
	    			}
	    			Channel bigChannel = (Channel) this.getInfoChannelCache().get("[channel]["+bcc.getChannelId()+"]");
	    			if(bigChannel == null){
	    				bigChannel = this.getChannelDAO().findChannelById(bcc.getChannelId());
	    				this.getInfoChannelCache().add("[channel]["+bcc.getChannelId()+"]",bigChannel);
	    			}
	    			info.setSmallChannel(smallChannel);
	    			info.setChannel(bigChannel);
	    		}else{
		    		ChannelContact scc = this.getChannelContactDAO().findChannelContactById(info.getCcid());
		    		info.setSmallChannel(this.getChannelDAO().findChannelById(scc.getChannelId()));
		    		ChannelContact bcc = this.getChannelContactDAO().findChannelContactById(scc.getParentId());
		    		info.setChannel(this.getChannelDAO().findChannelById(bcc.getChannelId()));
	    		}
			}
			return l;
		}
	}

	/**
	 * 获取Info列表
	 * 
	 * @param orderby
	 *            String
	 * @param ascOrDesc
	 *            int
	 * @param firstResult
	 *            int
	 * @param maxResults
	 *            int
	 * @return List
	 * 			Info对象列表
	 */
	public List findInfos(long uid,long cid,long ccid,long areaId,long tradingareaId,int isbiz,int validated,int status,int isprofile,String title,List ids, OrderObj[] oo){
		return this.getInfoDAO().findInfos(uid, cid, ccid, areaId, tradingareaId, isbiz, validated, status, isprofile, title, ids, oo);
	}
	
	/**
	 * @param ccid
	 * @param isCommend
	 * @return long
	 * 		Info个数
	 */
	public long getCommendInfoNum(long ccid,int isCommend){
		return this.getInfoDAO().getCommendInfoNum(ccid, isCommend);
	}
	
	/**
	 * 根据频道代码获取信息个数
	 * @param code
	 * @return
	 */
	public long getInfoNumByCid(long cid,int validated){
		return this.getInfoDAO().getInfoNumByCid(cid, validated);
	}

}
